#include "File.h"

// INPUT FILE

bool FileInputStream::OpenFile(const char *fileName, E_FILE_TYPE fileType)
{
	// close file first if already open
	if(isOpen() == true)
		CloseFile();

	// open the file based on type
	if(fileType == E_TEXT_FILE)
		m_fileStream.open(fileName, std::ifstream::in);
	else
		m_fileStream.open(fileName, std::ifstream::in | std::ifstream::binary);

	// get the filesize
	m_fileStream.seekg(0, std::ios::end);
	m_fileSize = m_fileStream.tellg();
	m_fileStream.seekg(0, std::ios::beg);
	m_fileSize++;

	return (isOpen() == true);
}

void FileInputStream::CloseFile()
{
	m_fileStream.close();
}

void FileInputStream::SeekStreamToStart()
{
	// moves get pointer to the beginning of file
	m_fileStream.seekg(0, std::ios::beg);
}

void FileInputStream::SeekStreamToEnd()
{
	// moves get pointer to the end of file
	m_fileStream.seekg(0, std::ios::end);
}

void FileInputStream::SeekPast(int offset)
{
	// offsets get pointer based on current position
	m_fileStream.seekg(offset, std::ios::cur);
}

int FileInputStream::GetSeekPosition()
{
	// where the get pointer is currently
	return m_fileStream.tellg();
}

bool FileInputStream::Read(char *buffer, int bytesToRead)
{
	if(isOpen() == false || buffer == NULL || bytesToRead <= 0)
		return false;

	// pull the content into the buffer
	m_fileStream.read(buffer, bytesToRead);

	return true;
}

bool FileInputStream::Write(char *buffer, int bytesToWrite)
{
	// since we must implement this from the abstract class,
	//    just return false
	return false;
}

bool FileInputStream::isOpen()
{
	// check if file is open
	if(m_fileStream.is_open() == false)
		return false;

	return true;
}



// OUTPUT FILE

bool FileOutputStream::OpenFile(const char *fileName, E_FILE_TYPE fileType, bool truncate)
{
	// close file first if already open
	if(isOpen() == true)
		CloseFile();

	if(fileType == E_TEXT_FILE)
	{
		m_fileStream.open(fileName, std::ofstream::in |
                         (truncate ? std::ofstream::trunc : std::ofstream::app));
	} 
	else
	{
		m_fileStream.open(fileName, std::ofstream::in |
                         (truncate ? std::ofstream::trunc : std::ofstream::app) |
                          std::ofstream::binary);
	}

	return (isOpen() == true);
}

void FileOutputStream::CloseFile()
{
	m_fileStream.close();
}

void FileOutputStream::SeekStreamToStart()
{
	// moves get pointer to the beginning of file
	m_fileStream.seekp(0, std::ios::beg);
}

void FileOutputStream::SeekStreamToEnd()
{
	// offsets get pointer based on current position
	m_fileStream.seekp(0, std::ios::end);
}

void FileOutputStream::SeekPast(int offset)
{
	// offsets get pointer based on current position
	m_fileStream.seekp(offset, std::ios::cur);
}

int FileOutputStream::GetSeekPosition()
{
	// where the get pointer is currently
	return m_fileStream.tellp();
}

bool FileOutputStream::Read(char *buffer, int bytesToRead)
{
	// since we must implement this from the abstract class,
	//    just return false
	return false;
}

bool FileOutputStream::Write(char *buffer, int bytesToWrite)
{
	if(isOpen() == false || buffer == NULL || bytesToWrite <= 0)
		return false;

	m_fileStream.write(buffer, bytesToWrite);
	m_fileSize += bytesToWrite;

	return true;
}

bool FileOutputStream::isOpen()
{
	if(m_fileStream.is_open() == false)
		return false;

	return true;
}
